home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / mweb / MWEB Utils / ws295sdk.exe / Ws2sdkzp.exe / SAMPLES / WS2CHAT / QUEUE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-06  |  5.8 KB  |  297 lines

  1. /*++
  2.  
  3. Copyright (c) 1995 Intel Corp
  4.  
  5. Module Name:
  6.  
  7.     queue.h
  8.  
  9. Abstract:
  10.  
  11.     Implementation of functions supplied by this queue manager module.
  12.  
  13. --*/
  14.  
  15. #include <stdio.h>
  16. #include <malloc.h>
  17. #include "queue.h"
  18.  
  19.  
  20.  
  21.  
  22. PQUEUE
  23. QCreate(void)
  24. /*++
  25.  
  26. Routine Description:
  27.  
  28.     Creates a new QUEUE, initializes it, and returns it. Returns NULL
  29.     if memory cannot be allocated in the heap.
  30.  
  31. Arguments:
  32.  
  33.     None.
  34.  
  35. Return Value:
  36.  
  37.     NULL if memory allocation fails; else a pointer to a new queue.
  38.  
  39. --*/
  40. {
  41.  
  42.     PQUEUE Queue; // points to the new queue
  43.  
  44.     // Allocate space for a new queue.
  45.     Queue = (PQUEUE)malloc(sizeof(QUEUE));
  46.     if (Queue != NULL){
  47.  
  48.         // Initialize the new queue.
  49.         Queue->Head = Q_NULL;
  50.         Queue->Tail = Q_NULL;
  51.         InitializeCriticalSection(&Queue->CrSec);
  52.     }
  53.     return(Queue);
  54. }
  55.  
  56.  
  57.  
  58.  
  59. void
  60. QFree(PQUEUE Queue)
  61. /*++
  62.  
  63. Routine Description:
  64.  
  65.     This function removes any items left on the queue, frees them, and
  66.     then frees the queue itself.
  67.  
  68. Arguments:
  69.  
  70.     Queue -- Pointer to the queue to free.
  71.  
  72. Return Value:
  73.  
  74.     None.
  75.  
  76. --*/
  77. {
  78.  
  79.     LPVOID Object; // points to objects we pull off the queue
  80.  
  81.     EnterCriticalSection(&Queue->CrSec);
  82.  
  83.     // Free everything on the queue.
  84.     Object = QRemove(Queue);
  85.     while (Object) {
  86.         free(Object);
  87.         Object = QRemove(Queue);
  88.     }
  89.  
  90.     LeaveCriticalSection(&Queue->CrSec);
  91.  
  92.     // Free the queue itself.
  93.     free(Queue);
  94. }
  95.  
  96.  
  97.  
  98.  
  99. LPVOID
  100. QRemove(PQUEUE Queue)
  101. /*++
  102.  
  103. Routine Description:
  104.  
  105.     This function dequeues one object from Queue and returns a generic
  106.     pointer to the object.  It is up to the calling function to know
  107.     the size and type of the object dequeued.
  108.  
  109. Arguments:
  110.  
  111.     Queue -- The queue from which to dequeue the object.
  112.  
  113. Return Value:
  114.  
  115.     NULL if the queue is empty; else, a pointer to the dequeued object.
  116.  
  117. --*/
  118. {
  119.  
  120.     LPVOID Data;    // points to the object we pull off the queue
  121.  
  122.     EnterCriticalSection(&Queue->CrSec);
  123.  
  124.     if (Queue->Head == Q_NULL){
  125.  
  126.         // If the queue is empty, we will return NULL.
  127.         Data = NULL;
  128.  
  129.     } else {
  130.  
  131.         // Get the pointer, NULL it in the QueueArray.
  132.         Data = Queue->QueueArray[Queue->Head];
  133.         Queue->QueueArray[Queue->Head] = NULL;
  134.  
  135.         // Check to see if we've just emptied the queue; if so, set
  136.         // the Head and Tail indices to Q_NULL.  If not, set the Head
  137.         // index to the right value.
  138.         if (Queue->Head == Queue->Tail) {
  139.             Queue->Head = Queue->Tail = Q_NULL;
  140.         } else {
  141.             Queue->Head = (Queue->Head + 1) % MAX_QUEUE_SIZE;
  142.         }
  143.     }
  144.  
  145.     LeaveCriticalSection(&Queue->CrSec);
  146.     return(Data);
  147. }
  148.  
  149.  
  150.  
  151.  
  152.  
  153. BOOL
  154. QInsert(
  155.     PQUEUE Queue,
  156.     LPVOID Object)
  157. /*++
  158.  
  159. Routine Description:
  160.  
  161.     This function enqueues one item into Queue, if there is room for
  162.     it.
  163.  
  164. Arguments:
  165.  
  166.     Queue -- The queue onto which to enqueue Object.
  167.  
  168.     Object -- A void pointer to the object being enqueued.
  169.  
  170. Return Value:
  171.  
  172.     TRUE -- The object was successfully enqueued.
  173.  
  174.     FALSE -- There were too many items already in the queue; one item
  175.     must be removed in order to insert another.
  176.  
  177. --*/
  178. {
  179.     BOOL ReturnValue; // holds the return value
  180.  
  181.     EnterCriticalSection(&Queue->CrSec);
  182.  
  183.     // If the queue is full, set the return value to FALSE and do
  184.     // nothing; if not, update the indices appropriately and set the
  185.     // return value to TRUE.
  186.     if(((Queue->Tail + 1) % MAX_QUEUE_SIZE == Queue->Head)
  187.        && (Queue->Head != Q_NULL)) {
  188.  
  189.         ReturnValue = FALSE;
  190.  
  191.     } else {
  192.  
  193.         Queue->Tail = (Queue->Tail + 1) % MAX_QUEUE_SIZE;
  194.         Queue->QueueArray[Queue->Tail] = Object;
  195.         if (Queue->Head == Q_NULL){
  196.             Queue->Head = 0;
  197.         }
  198.         ReturnValue = TRUE;
  199.     }
  200.  
  201.     LeaveCriticalSection(&Queue->CrSec);
  202.     return(ReturnValue);
  203. }
  204.  
  205.  
  206.  
  207.  
  208. BOOL
  209. QInsertAtHead(
  210.     PQUEUE Queue,
  211.     LPVOID Object)
  212. /*++
  213.  
  214. Routine Description:
  215.  
  216.     This function inserts one item at the HEAD of the queue.  Of
  217.     course, this violates queue semantics...but this can be useful at
  218.     times.
  219.  
  220. Arguments:
  221.  
  222.     Queue -- The queue into which to insert Object.
  223.  
  224.     Object -- A void pointer to the object being inserted.
  225.  
  226. Return Value:
  227.  
  228.     TRUE -- The object was successfully inserted at the head of the
  229.     queue.
  230.  
  231.     FALSE -- There were too many items already in the queue; one item
  232.     must be removed in order to insert another.
  233.  
  234. --*/
  235. {
  236.  
  237.     BOOL ReturnValue; // holds the return value
  238.  
  239.     EnterCriticalSection(&Queue->CrSec);
  240.  
  241.     // If the queue is full, set the return value to FALSE and do
  242.     // nothing; if not, update the indices appropriately and set the
  243.     // return value to TRUE.
  244.     if(((Queue->Tail + 1) % MAX_QUEUE_SIZE == Queue->Head)
  245.        && (Queue->Head != Q_NULL)) {
  246.  
  247.         ReturnValue = FALSE;
  248.  
  249.     } else {
  250.  
  251.         if (Queue->Head == Q_NULL) {
  252.  
  253.             // The queue was empty, so just use QInsert.
  254.             QInsert(Queue, Object);
  255.         }
  256.  
  257.         if (Queue->Head == 0) {
  258.             Queue->Head = MAX_QUEUE_SIZE - 1;
  259.         } else {
  260.             Queue->Head = Queue->Head - 1;
  261.         }
  262.  
  263.         Queue->QueueArray[Queue->Head] = Object;
  264.         ReturnValue = TRUE;
  265.     }
  266.  
  267.     LeaveCriticalSection(&Queue->CrSec);
  268.     return(ReturnValue);
  269. }
  270.  
  271.  
  272.  
  273.  
  274. BOOL
  275. QIsEmpty(PQUEUE Queue)
  276. /*++
  277.  
  278. Routine Description:
  279.  
  280.     This function tells the caller if the queue in question contains
  281.     any items.
  282.  
  283. Arguments:
  284.  
  285.     Queue -- The queue which we want to query.
  286.  
  287. Return Value:
  288.  
  289.     TRUE -- The queue is empty.
  290.  
  291.     FALSE -- The queue contains at least one item.
  292.  
  293. --*/
  294. {
  295.     return(Queue->Head == Q_NULL ? TRUE : FALSE);
  296. }
  297.